package com.hshit.downloader.io;

import java.io.IOException;
import java.io.InputStream;

import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpRequestBase;

import android.accounts.NetworkErrorException;
import android.content.Context;
import android.os.AsyncTask;

import com.hshit.downloader.utils.Utility;

/**
 * 
 * @author LongLT
 */
public class NetworkWorker extends AsyncTask<ShitRequest, Void, String> {
	public static final String TAG = NetworkWorker.class.getSimpleName();
	private ShitRequest request;
	private NetworkAsyncCallback<String> callback;
	private Context mContext;
	/**
	 * 
	 * @param request
	 * @param callback
	 */
	public NetworkWorker(Context mContext, ShitRequest request, NetworkAsyncCallback<String> callback) {
		setRequest(request);
		setCallback(callback);
		this.mContext = mContext;
	}
	
	Exception e;
	@Override
	protected String doInBackground(ShitRequest... request) {
		String text = "";
		InputStream in = null;
		try {
			in = openRequest(request[0]);
			text = Utility.inputStreamToString(in);
		} catch (ClientProtocolException e) {
			this.e = e;
			return "";
		} catch (IOException e) {
			this.e = e;
			return "";
		} catch (Exception e) {
			this.e = e;
			return "";
		} finally {
			if (in != null) {
				try {
					in.close();
				} catch (IOException e) {
				}
			}
		}
		return text;
	}
	
	/**
	 * 
	 */
	public void work() {
		execute(getRequest());
		if (getCallback() != null) getCallback().onStart(request);
	}
	
	/**
	 * 
	 * @param callback
	 */
	public void work(NetworkAsyncCallback<String> callback) {
		setCallback(callback);
		work();
	}
	
	@Override
	protected void onPostExecute(String result) {
		if (!result.equals("")) {
			if (getCallback() != null) getCallback().onSuccess(request, result);
		} else {
			if (getCallback() != null) getCallback().onFailed(request, e);
		}
	}
	
	/**
	 * 
	 * @param request
	 * @return
	 * @throws NetworkErrorException 
	 */
	protected InputStream openRequest(ShitRequest request) throws NetworkErrorException {
		HttpClient httpClient = request.prepareHttpClient();
		HttpRequestBase httpRequest = null;
		if(Utility.isNetWorkAvailabel(mContext)) {
			switch (request.getMethod()) {
			case ShitRequest.GET:
				httpRequest = request.prepareGetRequest();
				break;
			case ShitRequest.POST:
				httpRequest = request.preparePostRequest();
				break;
			case ShitRequest.DELETE:
				httpRequest = request.prepareDeleteRequestBody();
				break;
			}
		} else {
			throw new NetworkErrorException("Network not available.");
		}
		if (httpRequest != null) {
			HttpResponse response;
			try {
				response = httpClient.execute(httpRequest);
				return response.getEntity().getContent();
			} catch (ClientProtocolException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
		} else {
			return null;
		}
		return null;
	}
	
	// ========================================================================
	// Getters & setters
	// ========================================================================
	public NetworkAsyncCallback<String> getCallback() {
		return callback;
	}
	public void setCallback(NetworkAsyncCallback<String> callback) {
		this.callback = callback;
	}

	public ShitRequest getRequest() {
		return request;
	}
	public void setRequest(ShitRequest request) {
		this.request = request;
	}

	// ========================================================================
	// Callback
	// ========================================================================
	/**
	 * 
	 * @author LongLT
	 */
	public static interface NetworkAsyncCallback<T> {
		public void onStart(ShitRequest request);
		public void onSuccess(ShitRequest request, T response);
		public void onFailed(ShitRequest request, Exception e);
	}
}